package wesi;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Vector;

import javax.swing.JLabel;

public class DurchlaufTerminierung extends JLabel implements Runnable {
	private static final long serialVersionUID = 1L;
	
	private Vector<Auftrag> neueAuftraege = new Vector<Auftrag>();
    private int StartTerminMin = Integer.MAX_VALUE,  EndTerminMax = 0; // werden benötigt um Koordinatensystem
    																   // richtig zu skalieren
    private int PixelFaktor = 4; // 1 Tag = PixelFaktor Pixel
    int xAchsenLaenge, XAbschlag;
    int gezeichneterBereich;
    
    Thread runner;

    private enum Schriftfarbe {
        vergangenheit, aktuellePeriode, innerhalbTerminschranke, ausserhalbTerminSchranke, sonstiges
    };

    public void zeichneDLT() {
        runner.start();
    }

    public DurchlaufTerminierung(boolean WartetrichterNeuTerminierung) {
    	runner = new Thread(this);
    	setLayout(null);
    	neueAuftraege.clear();

    	if (WartetrichterNeuTerminierung) {        	
    		neueAuftraege.addAll(Main.Werkstatt.wt.getWartetrichterKomplett());            
    		Main.Werkstatt.wt.clearWartetrichter();         
    		Main.Werkstatt.wt.zeichneAuftragsBestand();
    	} else {
//    		neueAuftraege.addAll(Auftragsdatei.NeueAuftraegeTabelle.getNeueAuftraege());
    	}

    	// Starttermine berechnen
    	for (Auftrag a : neueAuftraege) {
    		//Wenn erweiterte Parameter nicht aktiviert sind
    		
    		if (Main.JButtonParameterAktivieren.isEnabled()== true){
    			a.BerechneStartTermin(GlobalParameters.getDurchlaufZeitAVG());

    			// kleinsten Starttermin suchen
    			if (a.getStarttermin() < StartTerminMin) {
    				StartTerminMin = a.getStarttermin();
    			}

    			// größten Endtermin suchen
    			if (a.getEndtermin() > EndTerminMax) {
    				EndTerminMax = a.getEndtermin();
    			}
    		}
    		else {
    			Parameter.AuftragsDFZ(a.plan); //Ermittlung auftragsbezogene DFZ
    			Parameter.AuftragsSZ(a.plan); //Ermittlung auftragsbezogene SZ        	
    			a.BerechneStartTermin(GlobalParameters.setDurchlaufZeitAVG()); //getDurchlaufZeitAVG() wird bei berechnung nicht berücksichtigt

    			// kleinsten Starttermin suchen
    			if (a.getStarttermin() < StartTerminMin) {
    				StartTerminMin = a.getStarttermin();
    			}

    			// größten Endtermin suchen
    			if (a.getEndtermin() > EndTerminMax) {
    				EndTerminMax = a.getEndtermin();
    			}
    		}
    	}

    	int PanelBreite;
    	// Start Termin Min liegt in der Zukunft
    	if (Zeit.getTag() < StartTerminMin) {
    		PanelBreite = 100 + (EndTerminMax - Zeit.getTag()) * PixelFaktor;
    	} else {
    		PanelBreite = 100 + (EndTerminMax - StartTerminMin) * PixelFaktor;
    	}

    	int PanelHoehe = 160 + 40 * neueAuftraege.size();

    	setPreferredSize(new Dimension(PanelBreite, PanelHoehe));
    	// Start Termin Min liegt in der Vergangenheit
    	if (StartTerminMin < Zeit.getTag()) {
    		xAchsenLaenge = (EndTerminMax - StartTerminMin) * PixelFaktor;
    		XAbschlag = StartTerminMin * PixelFaktor;
    	} else {
    		xAchsenLaenge = (EndTerminMax - Zeit.getTag()) * PixelFaktor;
    		XAbschlag = Zeit.getTag() * PixelFaktor;
    	}
    	xAchsenLaenge += 20;
    	XAbschlag -= 80;
    }
    
    public int countNeueAuftraege() {
        return this.neueAuftraege.size();
    }

    @Override
    protected void paintComponent(Graphics g) {

        Color aktuellePeriode = new Color(0, 175, 5);
//        Color Terminschranke = new Color(250, 247, 80);
        Color Terminschranke = new Color(255,155,0);

        // Legende
        g.setColor(aktuellePeriode);
        g.fillRect(10, 5, 15, 15);
        
        g.setColor(Color.BLACK);
        g.drawString("aktuelle Periode", 32, 17);
        
        g.setColor(Terminschranke);
        g.fillRect(130, 5, 15, 15);
        
        g.setColor(Color.BLACK);
        g.drawString("TerminSchranke", 152, 17);
        g.drawString("Vorgriffszeit(V) = Starttermin - Termin bei Bekanntwerden des Auftrags", 272, 17);

//        g.setColor(Color.BLACK);

        // x- Achse
        g.drawLine(50, 50, 50 + xAchsenLaenge, 50);

        // Werte für aktuellerTag und EndterminMax
        g.fillRect(50, 40, 2, 20);
        g.drawLine(Zeit.getTag() * PixelFaktor - XAbschlag, 45, Zeit.getTag() * PixelFaktor - XAbschlag, 55);
        g.drawString(String.valueOf(Zeit.getTag()), Zeit.getTag() * PixelFaktor - XAbschlag - 10, 40);

        g.drawLine(EndTerminMax * PixelFaktor - XAbschlag, 45, EndTerminMax * PixelFaktor - XAbschlag, 55);
        g.drawString(String.valueOf(EndTerminMax), EndTerminMax * PixelFaktor - XAbschlag - 10, 40);

        //Pfeil am Ende der X-Achse
        int xPunkte[] = {50 + xAchsenLaenge, 50 + xAchsenLaenge, 50 + xAchsenLaenge + 10};
        int yPunkte[] = {45, 55, 50};
        g.fillPolygon(xPunkte, yPunkte, xPunkte.length);

        // Einfärbungen aktuelle Periode + Terminschranke
        g.setColor(aktuellePeriode);
        int laengeAktuellePeriode = Zeit.getNaechsterPeriodenWechsel() - Zeit.getTag();
        g.fillRect(Zeit.getTag() * PixelFaktor - XAbschlag + 1, 51, laengeAktuellePeriode * PixelFaktor, 9);
        g.setColor(Terminschranke);
        g.fillRect((Zeit.getTag() * PixelFaktor) + laengeAktuellePeriode * PixelFaktor - XAbschlag, 51, GlobalParameters.getTerminSchranke() * GlobalParameters.getPeriodenLaenge() * PixelFaktor - GlobalParameters.getPeriodenLaenge() * PixelFaktor, 9);
        g.setColor(Color.BLACK);

        // Auftragsnummern
        int i = 0;
        for (Auftrag a : neueAuftraege) {
        	g.setColor(Color.BLACK);
            g.drawString(a.getAuftragsnummer(), 10, 40 * i + 100);
            // Auftrag ist nach dem Soll-Starttermin bekannt geworden!
            if (a.getStarttermin()- a.getBekanntGeworden() < 0){
            	g.setColor(Color.RED);
            		g.drawString("V(" + String.valueOf(a.getStarttermin()- a.getBekanntGeworden()) + ")", 10, 40 * i + 120);
            }
            // Auftrag ist for dem Soll-Starttermin bekannt geworden
            else{            	
            	g.drawString("V(" + String.valueOf(a.getStarttermin()- a.getBekanntGeworden()) + ")", 10, 40 * i + 120);
            }      
            i++;
        }
    }

    @Override
    public synchronized void run() {
        TabSimulation.deaktiviereHauptschalter();
        TabSimulation.aktiviereSchnelldurchlaufSchalter();
        
        int i = 0;
        for (Auftrag a : neueAuftraege) {       	
            // Markierung Endtermin
            add(new DLTBeschriftung(String.valueOf(a.getEndtermin()), 
            									   a.getEndtermin() * PixelFaktor - XAbschlag + 5, 
            									   40 * i + 90, 
            									   Schriftfarbe.sonstiges));
            warte();
            //Wenn erweiterte Parameter nicht aktiviert sind
            if (Main.JButtonParameterAktivieren.isEnabled()== true){
            //DLT-Elemente einfügen
            	for (int j = 0; j < a.getPlan().length; j++) {
            		add(new DLTElement((int) ((a.getEndtermin() - (j + 1) * GlobalParameters.getDurchlaufZeitAVG()) * PixelFaktor - XAbschlag), 40 * i + 100,  j));
            		warte();           
            	}
            }
            
            else{
            	Parameter.AuftragsSZ(a.plan);
            	Parameter.Auftragslaenge = a.getEndtermin() - a.getStarttermin();
            	Parameter.getAGLaenge(a);
            	int gezeichneterBereich = 0;
            	
            	for (int k = 0; k < a.getPlan().length; k++){
            		Parameter.VerteilungElemente(Parameter.AGLaenge.get(k), a.plan[k][0]);
            		
            		//Sicherheitszeit (nur einmal zu Beginn, da auftragsbezogen)
        			if(k == 0){        				
        				int SZ = (int) ((Parameter.getSZFaktor() * (Parameter.AuftragsSZ+0.5)));
        				add(new DLTElement((int) ((a.getEndtermin() - SZ) * PixelFaktor - XAbschlag ), 40 * i + 100, 0));
    					warte();
    					gezeichneterBereich=SZ;
        			}
            		for (int j = 1; j < 4; j++) {
            			switch(j){
		            		case 1:
		            			// DFZ 
		            			add(new DLTElement((int) ((a.getEndtermin() - (Parameter.Zeitelement[0] + gezeichneterBereich)) * PixelFaktor - XAbschlag ), 40 * i + 100, j));
	        					warte();
	        					gezeichneterBereich+=Parameter.Zeitelement[0];
	        					continue;            			
		            		case 2:
		            			//Liegezeit
		            			add(new DLTElement((int) ((a.getEndtermin() - (Parameter.Zeitelement[1] + gezeichneterBereich)) * PixelFaktor - XAbschlag ), 40 * i + 100, j));
	        					warte();
	        					gezeichneterBereich+=Parameter.Zeitelement[1];
	        					continue;    
		            		case 3:
		            			//Pauschalanteil
		            			add(new DLTElement((int) ((a.getEndtermin() - (Parameter.Zeitelement[2] + gezeichneterBereich)) * PixelFaktor - XAbschlag ), 40 * i + 100, j));
	        					warte();
	        					gezeichneterBereich+=Parameter.Zeitelement[2];
	        					break;   
            			}		
            		}       
            	}
            }	
            

            // Markierung Starttermin
            Schriftfarbe s;
            int TerminSchranke = Zeit.getTag() + GlobalParameters.getPeriodenLaenge() * GlobalParameters.getTerminSchranke();
            if (a.getStarttermin() < Zeit.getTag()) {
                s = Schriftfarbe.vergangenheit;
            } else if (a.getStarttermin() >= Zeit.getTag() & a.getStarttermin() < Zeit.getNaechsterPeriodenWechsel()) {
                s = Schriftfarbe.aktuellePeriode;
            } else if (a.getStarttermin() >= Zeit.getNaechsterPeriodenWechsel() & a.getStarttermin() < TerminSchranke) {
                s = Schriftfarbe.innerhalbTerminschranke;
            } else if (a.getStarttermin() >= TerminSchranke) {
                s = Schriftfarbe.ausserhalbTerminSchranke;
            } else {
                s = Schriftfarbe.sonstiges;
            }

            //int x = (a.getStarttermin() - (int) GlobalParameters.getDurchlaufZeitAVG()) * PixelFaktor - XAbschlag + 5;
            //Markierung Starttermin
            add(new DLTBeschriftung(String.valueOf((a.getStarttermin()-a.Anpassung)), 
            									   (a.getStarttermin() - 7 - a.Anpassung ) * PixelFaktor - XAbschlag + 5, 
            									   40 * i + 90, 
            									   s));
            if (i>=5){
                TabSimulation.richteJScrollPaneDurchlaufterminierungNachUntenAus(40 * i - 140);
            }
            warte();
            i++;
        }
        GlobalParameters.setzeGeschwindigkeitAufStandardGeschwindigkeit();
        TabSimulation.aktiviereHauptschalter();
        TabSimulation.deaktiviereSchnelldurchlaufSchalter();
       
    }

    private void warte() {
        try {
            Thread.sleep(GlobalParameters.getAblaufgeschwindigkeit());
        } catch (Exception e) {
        }
        repaint();

    }

    public Vector<Auftrag> getNeueAuftraege() {
        return this.neueAuftraege;
    }

    /** einzelne Elemente der Durchlaufgrafik*/    
    class DLTElement extends JLabel {
    	private static final long serialVersionUID = 1L;

    	Color gerade = new Color(85, 78, 255);
    	Color ungerade = new Color(255, 73, 246);
    	int i;
    	
    	/** int x-coordinate , int y-coordinate , int i = PositionsNummer des Elementes*/
    	DLTElement(int x, int y, int i) {
    		//Wenn erweiterte Parameter nicht aktiviert sind
    		if (Main.JButtonParameterAktivieren.isEnabled()== true){
    			setSize(new Dimension((int) (PixelFaktor * GlobalParameters.getDurchlaufZeitAVG()), 15));

    			setLocation(x, y);
    			this.i = i;
    		}

    		else {
    			switch(i){
    			case 0:
    				// Sicherheitszeit
    				setSize(new Dimension((int) (PixelFaktor *(Parameter.getSZFaktor() * (Parameter.AuftragsSZ+0.5))), 15));
    				setLocation(x, y);
    				this.i = i;
    				break;
    			case 1:
    				//DFZ       
    				setSize (new Dimension((int) (PixelFaktor *  Parameter.Zeitelement[0]),15));
    				setLocation(x, y);
    				this.i = i;
    				break;

    			case 2:
    				//Liegezeit            			
    				setSize (new Dimension((int) (PixelFaktor *  Parameter.Zeitelement[1]),15));
    				setLocation(x, y);
    				this.i = i;
    				break;

    			case 3:
    				//Pauschalanteil     
    				setSize (new Dimension((int) (PixelFaktor *  Parameter.Zeitelement[2]),15));
    				this.i = i;
    				setLocation(x, y);

    			}
    		} 
    	}

    	@Override
    	protected void paintComponent(Graphics g) {
    		//Wenn erweiterte Parameter nicht aktiviert sind
    		if (Main.JButtonParameterAktivieren.isEnabled()== true){

    			if (this.i % 2 == 0) {
    				g.setColor(gerade);
    			} else {
    				g.setColor(ungerade);
    			}
    			g.fillRect(0, 0, (int) (PixelFaktor * GlobalParameters.getDurchlaufZeitAVG()), 15);
    		}

    		else{
    			double d1 = 0.0;
    			//Abfrage fuer die unterschiedlichen Farben der Zeitelemente:

    			//Sicherheitszeit - Gelb
    			if (this.i == 0){
    				//
//    				g.setColor(Color.YELLOW);
    				g.setColor(new Color(255,155,0));
    				d1=PixelFaktor * (int)((Parameter.getSZFaktor() * (Parameter.AuftragsSZ+0.5)));
    			}
    			//DFZ - Grün
    			else if (this.i == 1){
    				g.setColor(Color.GREEN);
    				d1=PixelFaktor * Parameter.Zeitelement[0];
    			}
    			//Liegezeit - Rot
    			else if (this.i == 2){
    				g.setColor(Color.RED);
    				d1=PixelFaktor * Parameter.Zeitelement[1];
    			}
    			//Pauschalanteil - Blau
    			else if (this.i == 3){
    				g.setColor(Color.BLUE);
    				d1=PixelFaktor * Parameter.Zeitelement[2];
    			}
    			g.fillRect(0, 0, (int) (PixelFaktor * d1), 15);
    		}

    	}                            
    }

    // Beschriftungen für das DLT Diagramm
    class DLTBeschriftung extends JLabel {
		private static final long serialVersionUID = 1L;
		
		String Zahl;

        public DLTBeschriftung(String Zahl, int x, int y, Schriftfarbe s) {
            this.Zahl = Zahl;
            setSize(new Dimension(35, 20));
            setLocation(x, y);
            setText(this.Zahl);
            
            switch (s) {
                case vergangenheit:
                    setForeground(Color.GREEN);   // hellgrün: vor der aktuellen Periode
                    break;
                case aktuellePeriode:
                    setForeground(Color.green);   // in der aktuellen Periode
                    break;
                case innerhalbTerminschranke:
//                	setForeground(Color.YELLOW);
                    setForeground(new Color(255,155,0));  //nach der aktuellen Periode, aber vor der Terminschranke
                    break;
                case ausserhalbTerminSchranke:
                    setForeground(Color.RED);    // Soll-Starttermin liegt nach der Terminschranke, der Auftrag wird zurückgestellt
                    break;
                case sonstiges:
                    setForeground(Color.BLACK);
                    break;
                default:
                    setForeground(Color.BLACK);
            }
        }
     }
}
